/*
    SUSAN® - Sole of Unix Save ANything

   
      Copyright (C) 2011-2016 Skyatlas Co. LTD

   

   
*/

#ifndef BAREOS_LIB_PARSE_CONF_STATE_MACHINE_H_
#define BAREOS_LIB_PARSE_CONF_STATE_MACHINE_H_

#include "lib/lex.h"

class ConfigurationParser;
class BareosResource;
struct ResourceTable;
struct ResourceItem;

class ConfigParserStateMachine {
 public:
  ConfigParserStateMachine(const char* config_file_name,
                           void* caller_ctx,
                           LEX_ERROR_HANDLER* ScanError,
                           LEX_WARNING_HANDLER* scan_warning,
                           ConfigurationParser& my_config);
  ~ConfigParserStateMachine();
  ConfigParserStateMachine(ConfigParserStateMachine& ohter) = delete;
  ConfigParserStateMachine(ConfigParserStateMachine&& ohter) = delete;
  ConfigParserStateMachine& operator=(ConfigParserStateMachine& rhs) = delete;
  ConfigParserStateMachine& operator=(ConfigParserStateMachine&& rhs) = delete;

  enum class ParserError
  {
    kNoError,
    kResourceIncomplete,
    kParserError
  };

  ParserError GetParseError() const;

  bool InitParserPass();
  bool Finished() const { return parser_pass_number_ == 2; }

  bool ParseAllTokens();
  void DumpResourcesAfterSecondPass();

 public:
  LEX* lexical_parser_ = nullptr;

 private:
  enum class ParseInternalReturnCode
  {
    kGetNextToken,
    kNextState,
    kError
  };

  ParseInternalReturnCode ParserInitResource(int token);
  ParseInternalReturnCode ScanResource(int token);
  void FreeUnusedMemoryFromPass2();

  int config_level_ = 0;
  int parser_pass_number_ = 0;
  std::string config_file_name_;
  void* caller_ctx_ = nullptr;
  LEX_ERROR_HANDLER* scan_error_ = nullptr;
  LEX_WARNING_HANDLER* scan_warning_ = nullptr;
  ConfigurationParser& my_config_;

  struct {
    int rcode_ = 0;
    ResourceItem* resource_items_ = nullptr;
    BareosResource* allocated_resource_ = nullptr;
  } currently_parsed_resource_;

  enum class ParseState
  {
    kInit,
    kResource
  };

  ParseState state = ParseState::kInit;
};

#endif  // BAREOS_LIB_PARSE_CONF_STATE_MACHINE_H_
